﻿using DevExpress.XtraBars;
using DevExpress.XtraBars.Docking;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Grid.Customization;
using DevExpress.XtraSplashScreen;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SQLite;
using System.Diagnostics;
using System.IO;
using System.IO.Ports;
using System.Text;
using System.Windows.Forms;

namespace DevTeam
{
    public partial class DevMainForm : DevExpress.XtraBars.Ribbon.RibbonForm
    {
        private System.Windows.Forms.Timer timer = null;
        private Dictionary<string, DevForm> forms = new Dictionary<string, DevForm>();
        private bool restarting = false;
        private SerialPort portBarcodeScanner;
        public DevForm ActiveXForm = null;

        public DevMainForm()
        {
            InitializeComponent();
        }

        private void DevMainForm_Load(object sender, EventArgs e)
        {

            this.SuspendLayout();
            this.Hide();

            //Visual inheritance'ın design modunda hata vermemesi için eklendi.
            //Aksi halde mainform dan türeyen formların design moduna geçilemiyor.
            if (this.DesignMode)
                return;

            try
            {
                //var sw = Stopwatch.StartNew();

                DataTable dt = Session.DataManager.ExecuteDataTable(Session.GetLookupMapSp);
                foreach (DataRow r in dt.Rows)
                    Session.LookupMaps.Add(r["Field"].ToString(),
                        new Session.LookupMap(r["LookUpId"].ToInt(), r["Caption"].ToStr()));


                //sw.Stop();                
                //Session.MainForm.NotifyMain(sw.Elapsed.TotalSeconds.ToString("N1") + " sn.");

                //if (File.Exists(Session.sqlitefileDelete))
                //    throw new ApplicationException("Önceki oturumdan kalan hatalı dosya siliniyor.");
            }
            catch (Exception ex)
            {
                restarting = true;
                LogManager.LogToDB(ex);
                //Application.Restart();
                Application.ExitThread();
                return;
            }

            this.Text = Session.ApplicationName + (Session.Version != null ? " - v" + Session.Version : "");

            bsiUser.Caption = Session.CurrentUser.UserName + " / " + Session.DatabaseTipi;

            bsiDoviz.Caption = Session.GununKurlari;

            if (Session.isProblematicUser)
                this.AllowFormGlass = DevExpress.Utils.DefaultBoolean.False;
            else
                this.AllowFormGlass = Session.Settings.AllowFormGlass;

            this.FormClosing += MainForm_FormClosing;

            //TAŞINDI
            //string StartupRibbonPage = Session.PrgSettingsOrg.StartupRibbonPage.ToStr();
            //if (StartupRibbonPage != "")
            //    ribbon.SelectedPage = ribbon.Pages[Session.PrgSettingsOrg.StartupRibbonPage];

            this.KeyPreview = true;
            this.KeyDown += DevMainForm_KeyDown;

            InitializeTimer();
            JobManager.Init();

            dpSeason.Visibility = dpCustomer.Visibility = dpReport.Visibility = DockVisibility.Hidden;

            try
            {
                if (WhoAmI == 94)
                {
                    Session.MainForm.NotifyMain("BarcodeEnabled: '" + BarcodeEnabled.ToStr() + "'" + " BarcodeComPort: '" + BarcodeComPort.ToStr() + "'");
                }

                if (BarcodeEnabled)
                {
                    if (BarcodeComPort != "")
                    {
                        portBarcodeScanner = new System.IO.Ports.SerialPort(BarcodeComPort);
                        portBarcodeScanner.BaudRate = 57600;
                        portBarcodeScanner.DataBits = 8;
                        portBarcodeScanner.Parity = System.IO.Ports.Parity.Mark;
                        portBarcodeScanner.StopBits = System.IO.Ports.StopBits.One;
                        portBarcodeScanner.DtrEnable = true;
                        portBarcodeScanner.Open();
                        portBarcodeScanner.DataReceived += portBarcodeScanner_DataReceived;
                    }
                }
            }
            catch
            {
                XtraMessageBox.Show("Barkod okuyucu ayarlarında sorun var. Otomatik bağlantı kurulamadı.", "Hata", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            tabbedView.DocumentActivated += tabbedView_DocumentActivated;

            Ribbon.MdiMergeStyle = DevExpress.XtraBars.Ribbon.RibbonMdiMergeStyle.Always;
            Ribbon.Merge += ribbon_Merge;
            Ribbon.UnMerge += Ribbon_UnMerge;
        }

        RibbonPage lastRibbonPage = null;

        void Ribbon_UnMerge(object sender, RibbonMergeEventArgs e)
        {
            if (lastRibbonPage != null)
                Ribbon.SelectedPage = lastRibbonPage;
        }

        void ribbon_Merge(object sender, RibbonMergeEventArgs e)
        {
            if (e.MergedChild.PageCategories.Count > 0)
            {
                lastRibbonPage = e.MergeOwner.SelectedPage;
                e.MergeOwner.SelectedPage = e.MergedChild.PageCategories[0].Pages[0];
            }

        }

        void tabbedView_DocumentActivated(object sender, DevExpress.XtraBars.Docking2010.Views.DocumentEventArgs e)
        {
            SetActiveXFormFromMDIManager();

            if (tabbedView.ActiveDocument != null)
            {
                DevForm activeForm = tabbedView.ActiveDocument.Form as DevForm;

                foreach (DevExpress.XtraBars.Docking2010.Views.BaseDocument doc in tabbedView.Documents)
                {
                    DevForm form = doc.Form as DevForm;
                    if (form != null && form != activeForm)
                    {
                        foreach (CustomizationForm cf in form.CustomizationForms)
                            cf.Hide();
                    }
                }

                if (activeForm != null)
                {
                    foreach (CustomizationForm cf in activeForm.CustomizationForms)
                        if (!cf.IsDisposed)
                            cf.Show();
                }
            }
        }

        private void MainForm_Shown(object sender, EventArgs e)
        {
            //Visual inheritance'ın design modunda hata vermemesi için eklendi.
            //Aksi halde mainform dan türeyen formların design moduna geçilemiyor.
            if (this.DesignMode)
                return;

            Session.AcilisSuresi = (DateTime.Now - Session.LaunchingTime).TotalSeconds;

            try
            {
                FileInfo fInfo = new FileInfo(Session.SQLiteFile);
                Session.DataFileSize = (int)fInfo.Length;
            }
            catch
            {
            }

            Session.DataManager.ExecuteNonQuery("UpdLogPrg", WhoAmI, Session.Version, Session.DataFileSize, 0, Session.AcilisSuresi);

            Session.MainForm.ShowInTaskbar = true;

            this.WindowState = FormWindowState.Maximized;
            this.ResumeLayout();
            SplashScreenManager.CloseDefaultSplashScreen();

        }


        private void InitializeTimer()
        {
            if (!Session.isProblematicUser)
            {
                timer = new Timer();    //once a minute!
                timer.Interval = 60000;
                //timer.SynchronizingObject = this;
                timer.Tick += RaiseUpdate;
                timer.Enabled = true;
            }

            bwRefreshLk.DoWork += bwRefreshLk_DoWork;
            bwRefreshLk.RunWorkerCompleted += bwRefreshLk_RunWorkerCompleted;
        }

        void RaiseUpdate(object sender, EventArgs e)
        {
            timer.Enabled = false;
            RefreshData();
            timer.Enabled = true;
        }

        void bwRefreshLk_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            DataSet dsResult = e.Result as DataSet;
            if (dsResult != null)
            {
                RepositoryManager.dsLookups.Tables["Settings"].Clear();
                RepositoryManager.dsLookups.Merge(dsResult);

                if (dsResult.Tables.Contains("V_Kumas"))
                    RepositoryManager.InitProductDictionary();

                RepositoryManager.RemoveDeletedRows();
            }
        }

        public void SetTaskMessage(string message, Action onClick)
        {
            if (message == "")
                bbiTaskAlert.Visibility = BarItemVisibility.Never;
            else
            {
                bbiTaskAlert.Visibility = BarItemVisibility.Always;
                bbiTaskAlert.Caption = message;
            }

            this.bbiTaskAlert.ItemClick += delegate(object sender, ItemClickEventArgs e)
            {
                onClick();
            };
        }

        void bwRefreshLk_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            //todo:
            e.Result = Session.repositoryManager.RefreshData(RepositoryManager.dsLookups);
        }



        public delegate void PersistingHandler();
        public event PersistingHandler Persisting;

        public delegate void UserChangedHandler();
        public event UserChangedHandler UserChanged;

        public void PersistDsi()
        {

            try
            {
                if (Persisting != null)
                    Persisting();

                string connstr = "Data Source=" + Session.SQLiteFile + "; PRAGMA synchronous=off; PRAGMA journal_mode = MEMORY";

                bool yaz = true;
                if (File.Exists(Session.SQLiteFile))
                {
                    FileInfo fi = new FileInfo(Session.SQLiteFile);
                    if ((DateTime.Today - fi.LastWriteTime.Date).TotalDays < 3)
                        yaz = false;
                }

                if (yaz)
                {
                    this.Cursor = Cursors.WaitCursor;

                    SplashScreenManager.ShowForm(typeof(SplashSaving));

                    if (!File.Exists(Session.SQLiteFile))
                        SQLiteConnection.CreateFile(Session.SQLiteFile);

                    using (var con = new SQLiteConnection(connstr))
                    using (var cmd = new SQLiteCommand(con))
                    {
                        con.Open();
                        string sql = "";
                        foreach (KeyValuePair<string, string> pair in Session.SavedLookups)
                            sql += "DROP TABLE IF EXISTS " + pair.Key + ";" + pair.Value + ";";


                        cmd.CommandText = sql;
                        cmd.ExecuteNonQuery();
                    }

                    foreach (string savedLookup in Session.SavedLookups.Keys)
                        Upd(savedLookup, RepositoryManager.dsLookups.Tables[savedLookup], connstr);

                    SplashScreenManager.CloseDefaultSplashScreen();

                    this.Cursor = Cursors.Default;
                }
            }
            catch
            {
            }
        }

        private static void Upd(string tablename, DataTable dt, string connstr)
        {
            using (var con = new SQLiteConnection(connstr))
            {
                con.Open();
                using (SQLiteTransaction tr = con.BeginTransaction())
                using (var adapter = new SQLiteDataAdapter("SELECT * FROM " + tablename, con))
                {
                    using (adapter.InsertCommand = new SQLiteCommandBuilder(adapter).GetInsertCommand())
                    {
                        adapter.InsertCommand.Transaction = tr;
                        foreach (DataRow row in dt.Rows)
                            row.SetAdded();

                        var sw = Stopwatch.StartNew();
                        int numRowsUpdated = adapter.Update(dt);
                        sw.Stop();
                        double t2 = sw.Elapsed.TotalMilliseconds;
                        tr.Commit();
                    }
                }
            }
        }

        void MainForm_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
        {
            if (!restarting)
                PersistDsi();
        }

        public void NotifyMain(string message)
        {
            bsiInfo.Caption = DateTime.Now.ToLongTimeString() + " | " + message;
        }

        public void NotifySelectionInfo(DevForm frm)
        {
            if (frm != null && !frm.IsDisposed)
                bsiCustomSelectInfo.Caption = frm.SelectionInfo;
        }

        public DevForm ShowMdiChildForm(Type type, params object[] prm)
        {
            DevForm frm = GetActiveForm(type, prm);

            if (frm != null)
            {
                ActiveXForm = frm;
                return frm;
            }

            try
            {
                if (type.BaseType == typeof(DevPopupForm))
                {
                    using (DevForm popup = (DevForm)Activator.CreateInstance(type, prm))
                    {
                        Session.DataManager.ExecuteNonQuery("InsLogForm", WhoAmI, popup.GetType().ToString());
                        ActiveXForm = popup;
                        frm = popup;
                        popup.ShowDialog();
                    }
                }
                else
                {
                    frm = (DevForm)Activator.CreateInstance(type, prm);
                    if (frm.isPopup)
                    {
                        using (DevForm popup = (DevForm)Activator.CreateInstance(type, prm))
                        {
                            Session.DataManager.ExecuteNonQuery("InsLogForm", WhoAmI, popup.GetType().ToString());
                            ActiveXForm = popup;
                            frm = popup;
                            popup.ShowDialog();
                        }
                    }
                    else
                    {
                        frm.MdiParent = tabbedView.Manager.MdiParent;
                        frm.WindowState = FormWindowState.Maximized;
                        string hash = CryptoManager.GetObjectHash(type, prm);
                        forms.Add(hash, frm);
                        frm.Hash = hash;
                        Session.DataManager.ExecuteNonQuery("InsLogForm", WhoAmI, frm.GetType().ToString());
                        ActiveXForm = frm;
                        frm.Show();
                    }

                }
            }
            catch (Exception Ex)
            {
                XtraMessageBox.Show(Ex.InnerException.ToString());
            }

            return frm;
        }

        public int WhoAmI { get { return Session.WhoAmI; } }

        public DevForm GetActiveForm(Type type, params object[] prm)
        {
            DevForm frm;
            string hash = CryptoManager.GetObjectHash(type, prm);

            forms.TryGetValue(hash, out frm);

            if (frm != null)
                if (!frm.IsDisposed)
                {
                    frm.Activate();
                    return frm;
                }
                else
                    RemoveForm(hash);

            return null;
        }


        public void RemoveForm(string Hash)
        {
            if (Hash != null)       //Popup formlar da buraya geldiğinden, bu kontrol gerekli. Xpopup formlarda bu event e gelmesi engellenebilir.
                forms.Remove(Hash);
        }


        void portBarcodeScanner_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            string data = Session.MainForm.portBarcodeScanner.ReadExisting();

            if (data.EndsWith("\r\n"))
            {
                data = data.Replace("\r\n", "");
                if (WhoAmI == 94)
                {
                    Session.MainForm.NotifyMain("Barkod: '" + data + "'");
                }
                //ilk üç hane tip
                int type = data.Substring(0, 3).ToInt(-1);
                //son hane parity ve tip alanları atılınca geri kalan çıplak barkod
                int barcode = data.Substring(3, data.Length - 4).ToInt(-1);

                if (ActiveXForm != null && ActiveXForm.EnabledBarcodeTypes.Contains(type))
                    ActiveXForm.FireBarcodeRead(type, barcode);
            }
        }



        void DevMainForm_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.F12)
            {
                int result = LogManager.TakeScreenShot();
                XtraMessageBox.Show("Destek bilgisi gönderildi.", "DestekId:" + result.ToString());
            }
            else if (e.KeyCode == Keys.F12)
            {
                Session.EasyNav.ShowDialog();
            }
            else if (e.Control && e.KeyCode == Keys.F11)
            {
                XtraMessageBox.Show(Session.DataManager.ConnectionString.Split(";".ToCharArray())[0]);
            }
            if (Session.CurrentUser.isDeveloper)
            {
                if (e.Control && e.KeyCode == Keys.F2)
                {
                    ShowMdiChildForm(typeof(UserChanger));

                    if (UserChanged != null)
                        UserChanged();

                }
                else if (e.Control && e.KeyCode == Keys.F10)
                {
                    string copied = Clipboard.GetText();
                    string[] lines = copied.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    if (lines.Length > 0)
                    {
                        StringBuilder sb = new StringBuilder();
                        foreach (string line in lines)
                            sb.Append("'" + line + "',\r\n");

                        sb.Remove(sb.Length - 3, 3);
                        Clipboard.SetText("(" + sb.ToString().Replace("\r\n", "") + ")");
                    }
                }
                else if (e.Control && e.KeyCode == Keys.F9)
                {
                    string copied = Clipboard.GetText();
                    string[] lines = copied.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    if (lines.Length > 0)
                    {
                        StringBuilder sb = new StringBuilder();
                        foreach (string line in lines)
                            sb.Append(line + ",\r\n");

                        sb.Remove(sb.Length - 3, 3);
                        Clipboard.SetText("(" + sb.ToString().Replace("\r\n", "") + ")");
                    }
                }
            }
        }

        public void SetActiveXFormFromMDIManager()
        {
            //DockManagerUpdate+
            if (tabbedView.ActiveDocument == null)
                ActiveXForm = null;
            else
            {
                DevForm activeForm = tabbedView.ActiveDocument.Form as DevForm;
                ActiveXForm = activeForm;
            }
        }

        private void bbiRibbonSettings_ItemClick(object sender, ItemClickEventArgs e)
        {
            Session.OptionsForm.ShowDialog();
        }

        private void MainForm_MdiChildActivate(object sender, EventArgs e)
        {
            DevForm frm = (DevForm)this.ActiveMdiChild;
            NotifySelectionInfo(frm);
        }


        #region CustomActions
        public void Cikis()
        {
            Application.Exit();
        }

        public void RefreshData()
        {
            if (!bwRefreshLk.IsBusy)
                bwRefreshLk.RunWorkerAsync();

            //MainForm.OkuYetki();
        }

        public void DigerleriniKapat()
        {
            tabbedView.Controller.CloseAllButThis(tabbedView.ActiveDocument);
            //DockManagerUpdate+
            //int count = mdiManager.Pages.Count;
            //int i = 0;
            //while (count > 1)
            //{
            //    if (mdiManager.Pages[i] != mdiManager.SelectedPage)
            //    {
            //        mdiManager.Pages[i].MdiChild.Close();
            //        count--;
            //    }
            //    else
            //        i++;
            //}
        }

        public void HepsiniKapat()
        {
            //DockManagerUpdate+
            tabbedView.Controller.CloseAll();
            //int count = mdiManager.Pages.Count;
            //for (int i = 0; i < count; i++)
            //    mdiManager.Pages[0].MdiChild.Close();
        }
        #endregion

        public void ShowDockPanel(string caption)
        {
            DockPanel dpFound = null;
            foreach (DockPanel dp in dockManager.Panels)
            {
                if (dp.Text == caption)
                {
                    dpFound = dp;
                    break;
                }
            }
            dpFound.Visibility = DockVisibility.Visible;
            dpFound.Show();
        }

        public IContainer Components
        {
            get
            {

                return this.components;
                //return this.Container.Components}
            }
        }

        public static string BarcodeComPort { get; set; }

        public static bool BarcodeEnabled { get; set; }


    }
}